This package provides something of a replacement for GetKeys by maintaining a key map reflecting the state of each keyboard attached to the Mac via ADB. (This means it won't work with any Mac earlier than an SE.)
The acute intent of the package was to solve a problem a game developer was having with the Adjustable Keyboard, which appears on ADB as two keyboards. The ROM keyboard driver has one map and clears it whenever there is a key state change on a new keyboard. Consequently, it was impossible for said developer to allow users to steer on the numeric key pad and fire with the space bar.
In addition to solving the problem with the Adjustable Keyboard, this package is now a demonstration of several techniques, including:
• building a system extension
• using the ADB API
• "patching" ADB service routines
• building, installing, and using a driver
• mapping physical key codes to virtual key codes
Although this package does maintain a map for each keyboard, it does not provide an API for polling individual keyboards. You can only find out if a key with a given virtual key code is being held down on any keyboard. If you need to track multiple keyboards separately, I suggest adding to the driver Control and Status selectors for determining the number of keyboards being tracked, polling the Nth keyboard for a given virtual key code, etc.
When the extension file is built, it contains three resources, one each for a system extension ('INIT'), a driver ('Drvr'), and a custom code resource which contains the ADB service routine ('AKSR'). For each resource there is a CodeWarrior 7 project. To build the extension, first build "ADBKS Extension π". This will create the file "ADB Key Spy". To merge in the 'Drvr' resource, build "ADBKS Driver π", and to merge in the 'AKSR' resource, build "ADBKS Service Routine π".
Note that the driver is stored in a resource of type 'Drvr', not 'DRVR' as is more common. This is because the extension calls OpenDriver to determine whether a driver with the same name has already been installed. (This would most likely result from two copies of the extension being installed but might result from a collision between two otherwise unrelated drivers.) If the driver is not loaded, OpenDriver searches for a resource of type 'DRVR' and, if found, installs it into the unit table in a sub-optimal way. Since the extension has its own ideas of how the driver should be installed, the driver is in a resource of a type which OpenDriver will not find.
After tossing "ADB Key Spy" into your Extensions folder and restarting, the 'INIT' resource will run and install the driver, install the ADB service routine, and set up the communication between the driver and the ADB service routine. The 'INIT' resource itself is not resident. The ADB service routine code resource handle is detached and "leaked" into the system heap -- e.g. no program holds onto a copy of the handle. This is perfectly intentional, as access to the handle is not useful once the ADB service routine has been installed.
When the extension is completely installed, the ADB service routine will automagically maintain its key state maps while the user types, etc., and the maps can be queried via calls to the driver. After updating its maps, the ADB service routine calls through to the ROM keyboard driver so that GetKeys continues to work and keyboard events continue to be posted.
Note that debugging the ADB service routine is difficult, since MacsBug (and likely other debuggers) depend on ADB for keyboard services. Do not attempt to set full-stop breakpoints in the ADB service routine, because they will render your machine unusable until you hit whatever reset button is present on your model. This does not mean you cannot use such things as DebugStr, however; see the comments in "ADBKS Service Routine.c" for details.
If you wish to ship ADB Key Spy with your product, please send email via AppleLink to SW.LICENSE or via internet to <sw.license@applelink.apple.com>.